networkx
Graph theory deals with various properties and algorithms concerned with Graphs. Although it is very easy to implement a Graph ADT in Python, we will use networkx
library for Graph Analysis as it has inbuilt support for visualizing graphs. In future versions of networkx
, graph visualization might be removed. When this happens, it is required to modify some parts of this chapter
import
statementThroughout this tutorial, we assume that you have imported networkx
as follows
In [38]:
import networkx as nx
In [39]:
G = nx.Graph()
By definition, a Graph
is a collection of nodes (vertices) along with identified pairs of nodes (called edges, links, etc). In NetworkX, nodes can be any hashable object e.g. a text string, an image, an XML object, another Graph, a customized node object, etc. (Note: Python's None object should not be used as a node as it determines whether optional function arguments have been assigned in many functions.)
In [40]:
G.add_node(1)
add a list of nodes,
In [41]:
G.add_nodes_from([2,3])
In [42]:
G.add_edge(1,2)
e=(2,3)
G.add_edge(*e) # Unpacking tuple
by adding a list of edges,
In [43]:
G.add_edges_from([(1,2),(1,3)])
we add new nodes/edges and NetworkX quietly ignores any that are already present.
At this stage the graph G consists of 3 nodes and 3 edges, as can be seen by:
In [44]:
G.number_of_nodes()
Out[44]:
In [45]:
G.number_of_edges()
Out[45]:
In addition to the methods Graph.nodes
, Graph.edges
, and Graph.neighbors
, iterator versions (e.g. Graph.edges_iter
) can save you from creating large lists when you are just going to iterate through them anyway.
Fast direct access to the graph data structure is also possible using subscript notation.
Warning
Do not change the returned dict
--it is part of the graph data structure and direct manipulation may leave the graph in an inconsistent state.
In [46]:
G.nodes()
Out[46]:
In [47]:
G.edges()
Out[47]:
In [48]:
G[1]
Out[48]:
In [49]:
G[1][2]
Out[49]:
You can safely set the attributes of an edge using subscript notation if the edge already exists.
In [50]:
G[1][2]['weight'] = 10
In [51]:
G[1][2]
Out[51]:
Fast examination of all edges is achieved using adjacency iterators. Note that for undirected graphs this actually looks at each edge twice.
In [52]:
FG=nx.Graph()
FG.add_weighted_edges_from([(1,2,0.125),(1,3,0.75),(2,4,1.2),(3,4,0.375)])
for n,nbrs in FG.adjacency_iter():
for nbr,eattr in nbrs.items():
data=eattr['weight']
if data<0.5: print('(%d, %d, %.3f)' % (n,nbr,data))
In [53]:
list(FG.adjacency_iter())
Out[53]:
Convenient access to all edges is achieved with the edges
method.
In [54]:
for (u,v,d) in FG.edges(data='weight'):
if d<0.5: print('(%d, %d, %.3f)'%(n,nbr,d))
Attributes such as weights, labels, colors, or whatever Python object you like, can be attached to graphs, nodes, or edges.
Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but attributes can be added or changed using add_edge
, add_node
or direct manipulation of the attribute dictionaries named G.graph
, G.node
and G.edge
for a graph G
.
Assign graph attributes when creating a new graph
In [55]:
G = nx.Graph(day="Friday")
G.graph
Out[55]:
Or you can modify attributes later
In [56]:
G.graph['day']='Monday'
G.graph
Out[56]:
In [57]:
G.add_node(1,time = '5pm')
In [58]:
G.add_nodes_from([3], time='2pm')
In [59]:
G.node[1]
Out[59]:
In [60]:
G.node[1]['room'] = 714
In [61]:
G.nodes(data=True)
Out[61]:
Note that adding a node to G.node
does not add it to the graph, use G.add_node()
to add new nodes.
In [62]:
G.add_edge(1, 2, weight=4.7 )
In [63]:
G[1][2]
Out[63]:
In [64]:
G.add_edges_from([(3,4),(4,5)], color='red')
In [65]:
G.add_edges_from([(1,2,{'color':'blue'}), (2,3,{'weight':8})])
In [66]:
G[1][2]['weight'] = 4.7
In [67]:
G.edge[1][2]['weight'] = 4
In [68]:
G.edges(data=True)
Out[68]:
In [69]:
nx.to_numpy_matrix(G)
Out[69]:
In [70]:
nx.to_numpy_matrix(FG)
Out[70]:
In [71]:
%matplotlib inline
import matplotlib.pyplot as plt
In [72]:
nx.draw(FG)
Now we shall draw the graph using graphviz layout
In [73]:
from networkx.drawing.nx_agraph import graphviz_layout
pos = graphviz_layout(FG)
plt.axis('off')
nx.draw_networkx_nodes(FG,pos,node_color='g',alpha = 0.8) # draws nodes
nx.draw_networkx_edges(FG,pos,edge_color='b',alpha = 0.6) # draws edges
nx.draw_networkx_edge_labels(FG,pos,edge_labels = nx.get_edge_attributes(FG,'weight')) # edge lables
nx.draw_networkx_labels(FG,pos) # node lables
Out[73]:
We have only seen the basic graph functionalities. In addition to this, NetworkX provides many Graph Algorithms, and Many types of Graphs. Interested reader can look at Official Documentation